import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;


public class Principal {
	
	public static void main(String[] args) throws InterruptedException{
		
		Stack<Integer> jogadas = new Stack<Integer>(); //Pilha que será usada para identificar quem deve jogar (de onde esperar a entrada)
														//E a posicao da jogada (x, y)
		Integer tipo = -1; //Identifica o tipo do jogador, se eh cliente ou servidor (essa variavel fica sendo alternada para saber-se tbm quem joga
		
		
		ArrayList<String> nome_jogador1 = new ArrayList<String>(); //Usado para guardar o nome do jogador local
		nome_jogador1.add(""); //Coloca um nome vazio e fica esperando por um nome
		Leitor_tipo_nomeJogador leitor = new Leitor_tipo_nomeJogador(nome_jogador1); //Inicia a interface que le o nome do jogador e escolhe entre
										//Ser servidor e cliente
		leitor.setVisible(true);
		
		//Sincroniza sobre a lista que guarda o nome do jogador
		synchronized(nome_jogador1){
			try{
				while(nome_jogador1.get(0) == ""){ //Enquanto essa string for "", espera pela thread da interface grafica
					System.out.println("Esperando");
					nome_jogador1.wait();
				}
			}catch (InterruptedException e) {
				System.out.println("Problemas com a Thread");
			}
		}
		tipo = leitor.getTipo(); //Guarda o tipo (servidor ou cliente)
		
		
		//Parte principal, sincronizada pela pilha de jogadas
		synchronized (jogadas) {

			//Inicia a Thread que cuida da rede como servidor ou cliente. Na criacao da Thread ja se trocam os nomes dos jogadores
			ThreadRede rede = null;
			if(tipo == ThreadRede.SERVIDOR)
				rede = new ThreadRede(jogadas, leitor.getNome().get(0));
			else
				rede = new ThreadRede(jogadas, leitor.getNome().get(0),  leitor.getIp());
			
			//Monta os nomes dos jogadores
			Jogador j1 = new Jogador(leitor.getNome().get(0));
			Jogador j2 = new Jogador(rede.getNome_recebido());
			ArrayList<Jogador> jogadores = new ArrayList<Jogador>();
			//Cria a Thread que cuida da GUI
			ThreadGUI gui = new ThreadGUI(jogadas, j2,j1);
			
			//Criao jogo
			JogoDaVelha jogo = new JogoVelha();
			
			//Insere o tipo inicial nas jogadas (controlara quem comeca jogando)
			jogadas.push(leitor.getTipo());
			jogadores.add(j2);
			jogadores.add(j1);
			
			//Incia as outras duas Threads
			rede.start();
			gui.start();
			
			if(tipo == 0)
				gui.getGui().setEnabled(false); //Cliente comeca com a interface grafica desabilitada

			int terminou;
			int x, y;

			do{
				try{
					while(jogadas.size() == 1){ //Enquanto nao tem 3 valores na pilha de jogadas
						jogadas.wait();
					}
					y = jogadas.pop(); //Retira y e x
					x = jogadas.pop();
					terminou = jogo.joga(jogadores.get(jogadas.peek()), y, x); //Com com o devido jogador e recebe o fato de ter terminado ou nao
					if(jogadas.peek() == 0){ //Caso tenha lido da rede
						gui.getGui().setEnabled(true); //Habilita a interface grafica
						gui.marcaBotaoGUI(y, x); //Marca na posicao (x,y)
						jogadas.pop();
						jogadas.push(1); //Coloca o identificador do proximo a jogar
					}
					else{ //Caso tenha lido da interface
						rede.enviaInt(x);//Envia pela rede x e y, parte do protocolo
						rede.enviaInt(y);
						jogadas.pop();
						jogadas.push(0); 
						gui.getGui().setEnabled(false); 
					}

				}catch (InterruptedException e) {terminou = 0;}
				catch (IndexOutOfBoundsException e) {terminou = 0;}

			}while(terminou == 0);

			//gui.getGui().setVisible(false);
			Mensagem fim = null; //Fica responsavel por terminar a aplicacao
			if(terminou != -1)
				 fim = new Mensagem("O jogador(a) " +gui.getGui().getUltimaJogada() +" venceu!");
			else
				fim = new Mensagem("Ó nãããããão, deu Velha :/");
			fim.setVisible(true);

		
		
		}	
		
		
	}

}
